package fina2.dcs.fis;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;

import org.jboss.annotation.ejb.LocalBinding;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.datamodel.DataModel;
import org.jboss.seam.log.Log;

import fina2.dcs.common.UIComponentHelper;
import fina2.dcs.i18n.LanguageSession;
import fina2.dcs.system.SysString;
import fina2.dcs.system.SysStringLocal;
import fina2.dcs.system.SysStringPk;

@Stateful
@LocalBinding(jndiBinding = "BankTypeSession/local")
@Name("bankTypeSession")
@Scope(ScopeType.SESSION)
@AutoCreate
public class BankTypeSession implements BankTypeLocal,Serializable {
	@PersistenceContext
	private EntityManager em;
	
	@Logger
	private Log log;

	@DataModel
	private List<BankType> bankTypes = new ArrayList<BankType>();

	private BankType bankType = new BankType();

	private BankType selectedBankType = new BankType();

	private String selectedDesc = null;

	private String code = null;

	private boolean success = false;

	@EJB
	private SysStringLocal sysStringLocal;

	private final BigDecimal defaultIndex = new BigDecimal("1");

	public BankTypeSession() {

	}

	public void init() {
		log.info("Initializing Bank Types data...");

		try {

			bankType = new BankType();

			log.info("Getting All Bank Types");
			bankTypes = getAllBankTypes();

			List<BigDecimal> bankTypesNameStrid = new ArrayList<BigDecimal>();
			for (int i = 0; i < bankTypes.size(); i++) {
				bankTypesNameStrid.add(bankTypes.get(i).getNamestrid());
			}

			StringBuffer sb = new StringBuffer(bankTypesNameStrid.toString());
			sb.replace(0, 1, "");
			sb.replace(sb.toString().length() - 1, sb.toString().length(), "");

			List<SysString> bankTypesStrings = sysStringLocal.getAllValues(sb.toString(), LanguageSession.langId);
			for (int i = 0; i < bankTypes.size(); i++) {
				for (int j = 0; j < bankTypesStrings.size(); j++)
					if (bankTypes.get(i).getNamestrid().equals(bankTypesStrings.get(j).getPk().getId())) {
						bankTypes.get(i).setDescription(bankTypesStrings.get(j).getValue());
						break;
					}
			}
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}

	}

	public String addBankType() {
		try {

			BigDecimal sysMaxId = sysStringLocal.getMaxId().add(defaultIndex);
			bankType.setNamestrid(sysMaxId);
			bankType.setId(getMaxId().add(defaultIndex));
			bankType.setCode(bankType.getCode());
			em.persist(bankType);

			SysString ss = new SysString();
			SysStringPk pk = new SysStringPk(sysMaxId, LanguageSession.langId);
			ss.setPk(pk);
			ss.setValue(bankType.getDescription());
			sysStringLocal.addString(ss);

			success = true;

		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		} finally {
			bankType = new BankType();
		}

		return "bankTypeAdded";
	}

	public void removeBankType() {
		try {
			log.info("Removing bank type with code " + code);
			BankType bt = findByCode(code);
			BigDecimal id = bt.getNamestrid();
			em.remove(bt);
			SysStringPk pk = new SysStringPk(id, LanguageSession.langId);
			sysStringLocal.removeString(pk);
			success = true;
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}

	}

	public String updateBankType() {
		try {
			selectedBankType = em.merge(selectedBankType);

			SysStringPk pk = new SysStringPk(selectedBankType.getNamestrid(), LanguageSession.langId);
			SysString ss = sysStringLocal.findByPk(pk);
			ss.setValue(selectedDesc);
			sysStringLocal.updateString(ss);
			success = true;
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		} finally {
			selectedBankType = new BankType();
			selectedDesc = null;
		}

		return "bankTypeUpdated";
	}

	public BankType findByCode(String code) {
		BankType bt = null;
		try {
			log.info("Searching bank type with code " + code);
			bt = (BankType) em.createQuery("SELECT b FROM " + BankType.class.getName() + " b WHERE RTRIM(b.code)=:code").setParameter("code", code).getSingleResult();
		} catch (NoResultException ex) {
			log.info("Could not find bank type with code " + code);
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
		return bt;
	}

	public BankType findById(BigDecimal id) {
		BankType bt = null;
		try {
			
			bt = em.find(BankType.class, id);
			if (bt != null) {
				SysString ss = sysStringLocal.findByPk(new SysStringPk(bt.getNamestrid(), LanguageSession.langId));
				if (ss != null)
					bt.setDescription(ss.getValue());
			}
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
		return bt;
	}

	public BigDecimal getMaxId() {
		BigDecimal maxId = new BigDecimal("0");
		try {
			maxId = (BigDecimal) em.createQuery("SELECT MAX(id) FROM " + BankType.class.getName() + " b").getSingleResult();
			if (maxId == null)
				maxId = defaultIndex;
		} catch (NoResultException ex) {
			maxId = defaultIndex;
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
		return maxId;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public BankType getSelectedBankType() {

		return selectedBankType;
	}

	public void setSelectedBankType(BankType selectedBank) {
		UIComponentHelper.clearComponent(FacesContext.getCurrentInstance().getViewRoot());
		success = false;
		this.selectedBankType = selectedBank;
		selectedDesc = selectedBankType.getDescription();
	}

	public List<BankType> getBankTypes() {
		return bankTypes;
	}

	public void setBankTypes(List<BankType> bankTypes) {
		this.bankTypes = bankTypes;
	}

	public BankType getBankType() {
		return bankType;
	}

	public void setBankType(BankType bankType) {
		this.bankType = bankType;
	}

	@Remove
	@Destroy
	public void remove() {

	}

	public boolean isSuccess() {
		return success;
	}

	public void setSuccess(boolean success) {
		this.success = success;
	}

	public String getSelectedDesc() {
		return selectedDesc;
	}

	public void setSelectedDesc(String selectedDesc) {
		this.selectedDesc = selectedDesc;
	}

	@SuppressWarnings("unchecked")
	public List<BankType> getAllBankTypes() {
		return (List<BankType>) em.createQuery("FROM " + BankType.class.getName() + " b ORDER BY b.code ASC").getResultList();
	}
}
